use anyhow::{anyhow, Result};
use rand::Rng;
use std::sync::{mpsc, Arc};
use std::thread;
use std::time::Duration;

const NUM_PRODUCERS: usize = 4;

fn main() -> Result<()> {
    let (tx, rx) = mpsc::channel();
    let tx = Arc::new(tx);
    let mut handles = Vec::new();

    for i in 0..NUM_PRODUCERS {
        let tx_clone = tx.clone();
        let producer = thread::spawn(move || producer(i, tx_clone));
        handles.push(producer);
    }
    //手动drop tx 因为传递进去的都是tx.clone  否则rx无法结束
    drop(tx);
    let consumer = thread::spawn(move || {
        for x in rx {
            println!("thread received {x}");
        }
        Ok(())
    });
    handles.push(consumer);

    for x in handles {
        //x.join().unwrap()?;
        x.join()
            .map_err(|e| anyhow!("Thread join error:{:?}", e))?
            .expect("panic message");
    }
    Ok(())
}

fn producer(idx: usize, tx: Arc<mpsc::Sender<String>>) -> Result<()> {
    loop {
        let mut rng = rand::rng();
        let value = rng.random_range(0..100);
        let new_value = rng.random_range(10..90);
        // println!("Producing {} {}",value,new_value);
        let sheep_time = new_value * 10;
        tx.send(format!("{idx}-{value}"))?;
        thread::sleep(Duration::from_millis(sheep_time as u64));
        //random exit the producer
        if rng.random_range(100..900) % 10 == 0 {
            println!("{idx}结束");
            break;
        }
    }

    Ok(())
}
